home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / tvg103_s.zip / TVGRAPH.IN1 < prev    next >
Text File  |  1992-07-29  |  30KB  |  986 lines

  1. (*****************************************************************************)
  2. (*                                                                           *)
  3. (*  TVGRAPH Version 1.0 (C) C.L.Burke. Portions (C) Borland                  *)
  4. (*                                                                           *)
  5. (*  Display Specific routines                                                *)
  6. (*                                                                           *)
  7. (*  0. Do_Set_XXXXXX    - sets all of the functions into the procedure array *)
  8. (*                                                                           *)
  9. (*  1. Do_INIT_XXXXXX   - should initialise all the specific hardware        *)
  10. (*  2. Do_DONE_XXXXXX   - should reset all specific hardware                 *)
  11. (*  3. Do_PixelAddr_XXXXXX                                                   *)
  12. (*                      - in ax=y, bx=x | out AH=unshifted bit mask          *)
  13. (*                      - CL=bits to shift BX = byte offset                  *)
  14. (*  4. TVGraphCursorOn_XXXXXX                                                *)
  15. (*                        These 3 routines assume GLOBAL TvGraphCursor       *)
  16. (*                        has Start in H and end in L. GLOBAL TvGraphLoc     *)
  17. (*                        X in L and Y in H                                  *)
  18. (*                      - Turn Cursor on check TvViziFlag                    *)
  19. (*  5. TVGraphCursorOff_XXXXXX                                               *)
  20. (*                      - Turn Cursor off check TvViziFlag                   *)
  21. (*  6. TVUpdateCursor_XXXXXX                                                 *)
  22. (*                      - Update cursor to current specifications            *)
  23. (*  7. Do_GraphMOV_XXXXX- expect same parameters at REP MOVSW to text video  *)
  24. (*                      - CX = Number of words (HI=Attr,LO=Char) to move     *)
  25. (*                      - DS:SI = Source of words                            *)
  26. (*                      - ES:DI = Normal TEXT destination                    *)
  27. (*  8. NewJmp_GraphMOV_XXXXXX                                                *)
  28. (*                      - Replaces the CheckSnow code in Views unit          *)
  29. (*                      - important that the following structure is kept     *)
  30. (*                                                                           *)
  31. (*                        asm                                                *)
  32. (*                         call far ptr Do_GraphMOV_XXXXXX                   *)
  33. (*                         mov si,es                                         *)
  34. (*                         pop ax                                            *)
  35. (*                         pop cx                                            *)
  36. (*                         pop di                                            *)
  37. (*                         pop ds                                            *)
  38. (*                         pop es                                            *)
  39. (*                         db 0C3H   ( RET NEAR - can't use RET FAR!!!  )    *)
  40. (*                        end;                                               *)
  41. (*  9. procedure Draw_Any_Line_XXXXXX(X1,Y1,X2,Y2,Color:word); assembler;    *)
  42. (*          Generic draw routine assumes X1<X2                               *)
  43. (*                                                                           *)
  44. (* 10. procedure Draw_Horiz_Line_XXXXXX(X1,X2,Y,Color:word); assembler;      *)
  45. (*          Horizontal draw routine assumes X1<X2                            *)
  46. (*                                                                           *)
  47. (* 11. procedure Draw_Vert_Line_XXXXXX(X,Y1,Y2,Color:word); assembler;       *)
  48. (*          Vertical draw routine assumes Y1<Y2                              *)
  49. (*                                                                           *)
  50. (*****************************************************************************)
  51. const  (* EGA Specific constants *)
  52.   EGAVideoMemory     =$A000;
  53.   EGASequencer       =$03C4;
  54.   EGAGraphController =$03CE;
  55.   Set_EnableSR       =$0001;
  56.    UseSR             =$0F00;
  57.    UseCPUMask        =$0000;
  58.   Default_EnableSR   =Set_EnableSR+UseSR;
  59.   Set_RWFunction     =$0003;
  60.    OverWrite         =$0000;
  61.    LogicalAND        =$0800;
  62.    LogicalOR         =$1000;
  63.    LogicalXOR        =$1800;
  64.   Default_RWFunction =Set_RWFunction+OverWrite;
  65.   Set_WriteMode      =$0005;
  66.    Read_Mode_0       =$0000;
  67.    Read_Mode_1       =$0800;
  68.    Write_Mode_0      =$0000;
  69.    Write_Mode_1      =$0100;
  70.    Write_Mode_2      =$0200;
  71.    Write_Mode_3      =$0300;
  72.   Default_WriteMode  =Set_WriteMode+Read_Mode_1+Write_Mode_0;
  73.   Default_ColorPlane =$0007;
  74.   Default_Mask       =$FF08;
  75.  
  76.   BytesInLoop        =10;   (* Bytes in the simulated loop *)
  77.   NumberOfLoops      =16;   (* Number of coded loops *)
  78. var  (* GLobal to free BP in draw line routines *)
  79.  VARSlope:byte; (* 0 = slope < 1 , 1= slope >1 *)
  80.  BitShift,ReInitBit,NegBitShift,
  81.  CharMapPtr,VARVertIncr,VARIncr1,VARIncr2:word;
  82.  
  83.  
  84. Procedure Do_INIT_EGAVGA; assembler;
  85. asm
  86. (* Call once at start of program *)
  87. (* all ega/vga routines should return to this state *)
  88.     push ax
  89.     push cx
  90.     push dx
  91.     push es
  92.     push si
  93.  
  94.     xor ah,ah
  95.     xor ch,ch
  96.     mov ax,[GraphWidth]
  97.     div [CharWidth]
  98.     mul [GraphHeight]
  99.     mov [ColorList],ax
  100.     mov si,ax
  101.     mov ax,[VideoBufferSeg]
  102.     mov es,ax
  103.  
  104.     mov dx,EGAGraphController (* Set up Graphics controller *)
  105.     mov ax,Default_EnableSR
  106.     out dx,ax
  107.     mov ax,Set_WriteMode+Read_Mode_1+Write_Mode_2 (* For Color init next *)
  108.     out dx,ax
  109.     mov ax,Default_RWFunction
  110.     out dx,ax
  111.     mov ax,Default_Mask
  112.     out dx,ax
  113.     mov ax,Default_ColorPlane
  114.     out dx,ax
  115.  
  116.  
  117.     mov al,0ffh
  118.     mov ch,010h
  119.     mov cl,0
  120.     (*  ES:SI = SCreen , CX=Count, DX=port *)
  121. @L10:
  122.     and es:[si],cl
  123.     inc si
  124.     inc cl
  125.     dec ch
  126.     jnz @L10
  127.  
  128.     mov ax,Default_WriteMode
  129.     out dx,ax
  130.  
  131.     (* Set up 16 colors at EGAScreenSegment:[SI] where SI=max-x max-y *)
  132.     pop si
  133.     pop es
  134.     pop dx
  135.     pop cx
  136.     pop ax
  137.     ret
  138. end;
  139.  
  140.  
  141. Procedure Do_DONE_EGAVGA; assembler;
  142. asm
  143. (* Call once at end of program *)
  144.     push ax
  145.     push dx
  146.     mov dx,EGAGraphController  (* Set up Graphics controller *)
  147.     mov ax,Default_Mask  (* Restore CRT registers *)
  148.     out dx,ax
  149.     mov ax,Set_WriteMode+Read_Mode_0+Write_Mode_0
  150.     out dx,ax
  151.     mov ax,Set_RWFunction+OverWrite
  152.     out dx,ax
  153.     mov ax,Default_ColorPlane
  154.     mov ah,0Fh
  155.     out dx,ax
  156.     pop dx
  157.     pop ax
  158.     ret
  159. end;
  160.  
  161. procedure Do_PixelAddr_EGAVGA; assembler;
  162. asm
  163. (* in ax=y, bx=x | *)
  164. (* CL=bits to shift BX = byte offset *)
  165. (* BX=Y*80+X/8 = Y*64+Y*16+X/8 = Y SHL 4 + Y SHL 6 + X SHR 3 *)
  166. (* CL=BL and 7 *)
  167.        mov ch,bl
  168.        and ch,7   (* mask *)
  169.        mov cl,3
  170.        shr bx,cl  (* bx=X/8 *)
  171.        inc cl
  172.        shl ax,cl  (* ax=Y*16 *)
  173.        add bx,ax  (* bx=Y*16+X/8 *)
  174.        shl ax,1
  175.        shl ax,1   (* ax=Y*64 *)
  176.        add bx,ax  (* bx=Y*64+Y*16+X/8 *)
  177.        mov cl,ch
  178. end;
  179.  
  180. procedure Do_Cursor_EGAVGA; assembler;
  181. asm
  182. (* Expect CH = start, CL = stop line (0..16), - in TvGraphCursor*)
  183. (* Expect X in DL, Y in DH - character co-ords - in TvGraphPos *)
  184.     push cx
  185.     push dx
  186.     push si
  187.     push es
  188.     xor [TvViziFlag],0FFh
  189.     mov cx,[TvGraphCursor]
  190.     mov dx,[TvGraphLoc]
  191.  
  192.     and cx,01F1Fh  (* ensure each is 0..31 only *)
  193.     cmp cl,ch
  194.     jb @SKIP
  195.     push cx
  196.     mov al,CharHeight
  197.     mul dh         (* ax:= Y*CharHeight *)
  198.  
  199.     xor dh,dh
  200.     mov si,dx      (* Si = X *)
  201.  
  202.     xchg ch,cl
  203.     xor ch,ch
  204.     add ax,cx      (* ax:= Y*CharHeight+StartLine *)
  205.     mov cx,80
  206.     mul cx         (* ax:= (Y*CharHeight+StartLine)*80 *)
  207.     add ax,dx      (* ax:= (Y*CharHeight+StartLine)*80 *)
  208.     add si,ax      (* si:= (Y*CharHeight+StartLine)*80 + X *)
  209.     pop cx
  210.     mov al,cl
  211.     xor ah,ah
  212.     sub al,ch      (* al:= (StopLine - StartLine) *)
  213.     inc al         (* al:= (StopLine - StartLine)+1 *)
  214.     mov cx,ax      (* use as loop count *)
  215.     mov ax,[VideoBufferSeg] (* VideoBufferSeg  *)
  216.     mov es,ax
  217.     cli
  218.     mov dx,EGAGraphController (* Set up Graphics controller *)
  219.     mov ax,Default_EnableSR
  220.     out dx,ax
  221.     mov ax,Default_ColorPlane
  222.     out dx,ax
  223.     mov ax,Set_WriteMode+Read_Mode_1+Write_Mode_2
  224.     out dx,ax
  225.     mov ax,Default_Mask
  226.     out dx,ax
  227.     mov ax,Set_RWFunction+LogicalXOR
  228.     out dx,ax
  229.     mov al,0ffh
  230.  
  231.     (*  ES:SI = SCreen , AX=Temp, CX=Count, DX=port *)
  232. @L10:
  233.     and es:[si],al
  234.     add si,80
  235.     loop @L10
  236.     sti
  237. @SKIP:
  238.     pop es
  239.     pop si
  240.     pop dx
  241.     pop cx
  242.  
  243.     ret
  244. end;
  245.  
  246. procedure TVGraphCursorOn_EGAVGA; assembler;
  247. asm
  248.  cmp TvViziFlag,0
  249.  jne @OnOK
  250.  jmp Do_Cursor_EGAVGA
  251. @OnOK:
  252.  ret
  253. end;
  254.  
  255. procedure TVGraphCursorOff_EGAVGA; assembler;
  256. asm
  257.  cmp TvViziFlag,0
  258.  je @OffOK
  259.  jmp Do_Cursor_EGAVGA
  260. @OffOK:
  261.  ret
  262. end;
  263.  
  264. procedure TVUpdateCursor_EGAVGA; assembler;
  265. asm
  266.  test TvGraphCursor,$E000
  267.  jz @DOIRET_ON
  268.  jmp TvGraphCursorOff_EGAVGA
  269. @DOIRET_ON:
  270.  jmp TvGraphCursorOn_EGAVGA
  271. end;
  272.  
  273. procedure Do_GraphMOV_EGAVGA; assembler;
  274. asm
  275. (* Expect CX = Number of words (HI=Attr,LO=Char) to move *)
  276. (* Expect DS:SI = Source of words *)
  277. (* Expect ES:DI = Normal TEXT destination *)
  278.  
  279.     push es
  280.     push bp
  281.     push dx
  282.     push bx  (* Save register that may be changes by a TP procedure *)
  283.     push bp
  284.  
  285.     mov dx,ds
  286.     mov ax,seg @data  (* Set up data segment *)
  287.     mov ds,ax
  288.     mov es,ax
  289.     mov [TextSource.S],dx
  290.     mov [TextSource.O],si
  291.     mov [Count],cx
  292.  
  293.     call MouseCursorOff
  294.     call TvGraphCursorOff_EGAVGA
  295.  
  296.     mov ax,di
  297.     xor dx,dx
  298.     mov cx,0A0h
  299.     div cx            (* dx= O mod 160 , ax= O div 160 *)
  300.     shr dx,1
  301.     mov bx,dx         (* X=bx  , Y=ax *)
  302.  
  303.     mul [CharHeight]            (* ax := Y(text)*Rowsperline *)
  304.  
  305.     mov dx,80 (*BytesPerLine*)
  306.     mul dx
  307.     add bx,ax         (* End Routine PixelAddr10 *)
  308.                       (* BX -> offset to Buffer *)
  309.     mov [DestOfs],bx
  310.  
  311.     shr di,1          (* Convert index to one with no attributes *)
  312.     add di,offset GraphWriteAvail
  313.     mov [TextDest],di
  314.  
  315.     mov al,NumberOfLoops
  316.     mov bl,BytesInLoop
  317.     sub al,[CharHeight]    (* Number of loop segments to skip *)
  318.     and al,0Fh             (* ensure in range 0..15 *)
  319.     mul bl                 (* Number of bytes to skip   *)
  320.     add ax,OFFSET @STARTLP (* Location to jump to *)
  321.     mov [SaveJump],ax              (* DX has offset to jump to using jmp [dx] *)
  322.  
  323. @GLP1:
  324.     les si,[TextSource]
  325.     mov ax,es:[si]
  326.  
  327.     mov bl,ah          (* BL has Attr *)
  328.     mov bh,ah
  329.     mov cl,4
  330.     and bl,00Fh
  331.     and bh,0F0h
  332.     shr bh,cl           (* bh = background, bl = foreground *)
  333.  
  334.     mov di,[TextDest]
  335.     cmp ah,0ffh
  336.     jz  @NotText         (* ffh is attr signal for graphics *)
  337.     mov byte ptr [di],0
  338.     jmp @IsText
  339. @NotText:
  340.     mov byte ptr [di],al (* when attr=FF then char is window number *)
  341.     mov bx,0             (* Foreground 0 background 0 *)
  342.     mov ax,20h           (* Space character *)
  343. @IsText:
  344.     xor ah,ah           (* AX has character *)
  345.  
  346.     les di,[PtrFontTable]  (* shl by 4 = *16 for index into font table *)
  347.     shl ax,cl
  348.     add di,ax           (* ES:DI = font table for character *)
  349.  
  350.     xor ch,ch
  351.  
  352.     mov cl,bh           (* Background color *)
  353.     mov bp,[ColorList]  (* EGAScreenSegment:BP = List of colors in ega memory *)
  354.     add bp,cx           (* EGAScreenSegment:BP = actual color pointer in ega *)
  355.  
  356.     mov cl,[CharHeight] (* CL has height = times to do @L10 *)
  357.  
  358.     mov cx,[SaveJump]   (* Get the jump location *)
  359.  
  360.     push ds
  361.     mov ax,[VideoBufferSeg] (* VideoBufferSeg  *)
  362.     mov si,[DestOfs]
  363.     mov ds,ax           (* DS:SI = Screen Address *)
  364.  
  365.     (* ES:DI = Font, DS:SI = SCreen , AX=Temp, BX= attr, CX=Count, DX=port *)
  366.     (* DS:BP = location of color in ega memory *)
  367.  
  368.     cli
  369.     mov dx,EGAGraphController (* Set up Graphics controller *)
  370.     mov ax,Default_EnableSR
  371.     out dx,ax
  372.     mov ax,Default_WriteMode
  373.     out dx,ax
  374.     mov ax,Default_RWFunction
  375.     out dx,ax
  376.     mov ax,Default_ColorPlane
  377.     out dx,ax
  378.  
  379.     mov ah,ds:[bp]      (* Latch background color to memory *)
  380.     mov al,00
  381.     mov ah,bl
  382.     out dx,ax           (* foreground color to Set/Reset register *)
  383.  
  384.     mov al,8
  385.     mov bl,0FFh
  386.  
  387.     jmp cx            (* jump to start should be 0 for 16, 2 for 14 *)
  388.  
  389. @STARTLP:
  390. (* 0 *)                            (* CYCLES / BYTES *)
  391.     mov ah,es:[di]                 (*  4     /  3    *)
  392.     out dx,ax                      (* 11     /  1    *)
  393.     mov [si],bl                    (*  4     /  2    *)
  394.     inc di                         (*  2     /  1    *)
  395.     add si,80 (*BytesPerLine*)     (*  2     /  3    *)
  396. (* 1 *)                            (* 23     / 10    TOTAL *)
  397.     mov ah,es:[di]
  398.     out dx,ax
  399.     mov [si],bl
  400.     inc di
  401.     add si,80 (*BytesPerLine*)
  402. (* 2 *)
  403.     mov ah,es:[di]
  404.     out dx,ax
  405.     mov [si],bl
  406.     inc di
  407.     add si,80 (*BytesPerLine*)
  408. (* 3 *)
  409.     mov ah,es:[di]
  410.     out dx,ax
  411.     mov [si],bl
  412.     inc di
  413.     add si,80 (*BytesPerLine*)
  414. (* 4 *)
  415.     mov ah,es:[di]
  416.     out dx,ax
  417.     mov [si],bl
  418.     inc di
  419.     add si,80 (*BytesPerLine*)
  420. (* 5 *)
  421.     mov ah,es:[di]
  422.     out dx,ax
  423.     mov [si],bl
  424.     inc di
  425.     add si,80 (*BytesPerLine*)
  426. (* 6 *)
  427.     mov ah,es:[di]
  428.     out dx,ax
  429.     mov [si],bl
  430.     inc di
  431.     add si,80 (*BytesPerLine*)
  432. (* 7 *)
  433.     mov ah,es:[di]
  434.     out dx,ax
  435.     mov [si],bl
  436.     inc di
  437.     add si,80 (*BytesPerLine*)
  438. (* 8 *)
  439.     mov ah,es:[di]
  440.     out dx,ax
  441.     mov [si],bl
  442.     inc di
  443.     add si,80 (*BytesPerLine*)
  444. (* 9 *)
  445.     mov ah,es:[di]
  446.     out dx,ax
  447.     mov [si],bl
  448.     inc di
  449.     add si,80 (*BytesPerLine*)
  450. (*10 *)
  451.     mov ah,es:[di]
  452.     out dx,ax
  453.     mov [si],bl
  454.     inc di
  455.     add si,80 (*BytesPerLine*)
  456. (*11 *)
  457.     mov ah,es:[di]
  458.     out dx,ax
  459.     mov [si],bl
  460.     inc di
  461.     add si,80 (*BytesPerLine*)
  462. (*12 *)
  463.     mov ah,es:[di]
  464.     out dx,ax
  465.     mov [si],bl
  466.     inc di
  467.     add si,80 (*BytesPerLine*)
  468. (*13 *)
  469.     mov ah,es:[di]
  470.     out dx,ax
  471.     mov [si],bl
  472.     inc di
  473.     add si,80 (*BytesPerLine*)
  474. (*14 *)
  475.     mov ah,es:[di]
  476.     out dx,ax
  477.     mov [si],bl
  478.     inc di
  479.     add si,80 (*BytesPerLine*)
  480. (*15 *)
  481.     mov ah,es:[di]
  482.     out dx,ax
  483.     mov [si],bl
  484.     inc di
  485.     add si,80 (*BytesPerLine*)
  486.     sti
  487.  
  488.     pop ds
  489.     inc [TextSource.O]
  490.     inc [TextSource.O]
  491.     inc [TextDest]
  492.     inc [DestOfs]
  493.     dec [Count]
  494.     jnz @GLP1
  495.  
  496.     call MouseCursorOn
  497.     call TvUpdateCursor_EGAVGA
  498.  
  499.     pop bp
  500.     pop bx   (* Restore registers *)
  501.     pop dx
  502.     pop bp
  503.     pop es
  504.  
  505.     retf
  506. end;
  507.  
  508. procedure NewJmp_GraphMOV_EGAVGA; assembler;
  509. asm
  510.  call far ptr Do_GraphMOV_EGAVGA (* 5 *)
  511.  mov si,es                (* 2 *)  (* Normal Return code *)
  512.  pop ax                   (* 1 *)
  513.  pop cx                   (* 1 *)
  514.  pop di                   (* 1 *)
  515.  pop ds                   (* 1 *)
  516.  pop es                   (* 1 *)
  517.  db 0C3H   (* RET NEAR *) (* 1 *)
  518. end;                    (*TOTAL 13 bytes*)
  519.  
  520.  
  521. procedure Do_TextAddr_EGAVGA; assembler;
  522. asm
  523. (* start AX=Y, BX=X
  524. (* Output SI=CharMapPtr,BX=NegBitShift,DX=BitShift*)
  525. (*                     AX=ReInitBit *)
  526.      (* Calculate the start location of bitmap *)
  527.      DIV     [CharHeight]
  528.      MOV     CL,AH               (* Remainder = 0..Charheight-1 *)
  529.      MUL     [ScreenWidth]
  530.      SHR     BX,1
  531.      SHR     BX,1
  532.      SHR     BX,1
  533.      ADD     AX,BX                   (* AX is offset into table *)
  534.      ADD     AX,Offset GraphWriteAvail
  535.      mov     SI,AX
  536.  
  537.  
  538.      mov     ax,08000h
  539.      mov     bx,ax
  540.      mov     dx,ax
  541.  
  542. (* The following are used for determining when a character boundary has *)
  543. (* Been breached in graphics mode - bx and dx give the initial amount to*)
  544. (* rotate left - when carry inc SI i.e. adc si,0, ax give the normal one*)
  545. (* to initialize to when carry is found *)
  546.  
  547.      shr     bx,cl                  (* Head start for shifting initial -ive*)
  548.      sub     cl,[CharHeight]
  549.      neg     cl
  550.      dec     cl
  551.      shr     dx,cl                  (* Head start for shifting initial +ive *)
  552.      mov     cl,[CharHeight]
  553.      dec     cl
  554.      shr     ax,cl                  (* Head start for shifting normal +/- ive *)
  555. end;
  556.  
  557.  
  558.  
  559. procedure Draw_Vert_Line_EGAVGA(X,Y1,Y2:word;Color:byte); assembler;
  560. asm
  561. (* Assumes that Y1<Y2 for vertical lines *)
  562.        cli
  563.  
  564.        mov     ax,[Y1]
  565.        mov     bx,[X]
  566.        call    Do_TextAddr_EGAVGA
  567.        mov     [CharMapPtr],si
  568.        mov     [BitShift],dx
  569.        mov     [ReInitBit],ax
  570.  
  571.        mov     dx,EGAGraphController
  572.  
  573.        mov     ah,[Color]
  574.        xor     al,al
  575.        out     dx,ax
  576.  
  577.        mov     ax,Set_EnableSR+UseSR
  578.        out     dx,ax
  579.  
  580.        mov     ax,Default_RWFunction
  581.        mov     ah,[CurrentLineWriteMode]
  582.        shl     ah,1
  583.        shl     ah,1
  584.        shl     ah,1
  585.        out     dx,ax
  586.  
  587.        mov     ax,Default_WriteMode
  588.        out     dx,ax
  589.        mov     ax,Default_ColorPlane
  590.        out     dx,ax
  591.  
  592.  
  593.        mov     si,[BytesPerLine]
  594.        mov     ax,EGAVideoMemory
  595.        mov     es,ax
  596.        
  597.        mov     ax,[y1]         (* AX := y1 *)
  598.        mov     bx,[y2]         (* BX := y2 *)
  599.        mov     cx,bx
  600.        sub     cx,ax           (* CX := dy *)
  601.  
  602.        inc     cx              (* CX := # of pixels to draw *)
  603.        mov     bx,[x]          (* BX := x *)
  604.        push    cx              (* preserve this register *)
  605.        call    Do_PixelAddr_EGAVGA
  606.                                (* BX -> video buffer *)
  607.                                (* CL := # bits to shift right *)
  608. (* set up Graphics Controller *)
  609.        mov     ah,080h
  610.        shr     ah,cl           (* AH := bit mask in proper position *)
  611.        mov     al,8            (* AL := Bit Mask reg number *)
  612.        out     dx,ax
  613.  
  614.        pop     cx              (* restore this register *)
  615.  
  616. (* draw the line *)
  617. (* USES ES,BX,AL,SI,CX - avail DI,DX,AH,BP *)
  618.        mov     ah,[CurrentGraphWindow]
  619.        mov     di,[CharMapPtr]
  620.        mov     dx,[BitShift]         (* get rotated left, if carry then inc *)
  621.                                       (* bx from CharMapPtr *)
  622.  
  623. @L32:  cmp     byte ptr [di],ah
  624.        jne     @L32a
  625.        or      es:[bx],al      (* set pixel *)
  626. @L32a: add     bx,si           (* increment to next line *)
  627.        rol     dx,1                    (* rotate left when 1 inc bx *)
  628.        jnc     @L32b
  629.        add     di,si
  630.        mov     dx,[ReInitBit]
  631. @L32b: loop    @L32
  632.  
  633.        sti
  634. end;
  635.  
  636.  
  637.  
  638. procedure Draw_Horiz_Line_EGAVGA(X1,X2,Y:word;Color:byte); assembler;
  639. asm
  640.        cli
  641.        mov     ax,[Y]
  642.        mov     bx,[X1]
  643.        call    Do_TextAddr_EGAVGA
  644.        mov     [CharMapPtr],si
  645.  
  646.        mov     dx,EGAGraphController
  647.  
  648.        mov     ah,[Color]
  649.        xor     al,al
  650.        out     dx,ax
  651.  
  652.        mov     ax,Set_EnableSR+UseSR
  653.        out     dx,ax
  654.  
  655.        mov     ax,Default_RWFunction
  656.        mov     ah,[CurrentLineWriteMode]
  657.        shl     ah,1
  658.        shl     ah,1
  659.        shl     ah,1
  660.        out     dx,ax
  661.  
  662.        mov     ax,Default_WriteMode
  663.        out     dx,ax
  664.        mov     ax,Default_ColorPlane
  665.        out     dx,ax
  666.  
  667.        mov     si,[BytesPerLine]
  668.        mov     ax,EGAVideoMemory
  669.        mov     es,ax
  670.  
  671.        mov     ax,[Y]
  672.        mov     bx,[X1]
  673.        call    Do_PixelAddr_EGAVGA
  674.                                (* ES:BX -> video buffer *)
  675.                                (* CL := # bits to shift left *)
  676.        mov     di,bx           (* ES:DI -> buffer *)
  677.  
  678.        mov     dx,0FFFFh       (* DH := unshifted bit mask for leftmost *)
  679.                                (*        byte *)
  680.        shr     dh,cl           (* DH := bit mask for first byte *)
  681.  
  682.        mov     cx,[x2]
  683.        and     cl,7
  684.        xor     cl,7            (* CL := number of bits to shift left *)
  685.        shl     dl,cl           (* DL := bit mask for last byte *)
  686.  
  687. (* determine byte offset of first and last pixel in the line *)
  688.  
  689.        mov     ax,[x2]        (* AX := x2 *)
  690.        mov     bx,[x1]        (* BX := x1 *)
  691.  
  692.        mov     cl,3            (* number of bits to shift to *)
  693.                                (*  convert pixels to bytes *)
  694.  
  695.        shr     ax,cl           (* AX := byte offset of x2 *)
  696.        shr     bx,cl           (* BX := byte offset of x1 *)
  697.        mov     cx,ax
  698.        sub     cx,bx           (* CX := (# bytes in line) - 1 *)
  699.  
  700. (* get Graphics Controller port address into DX *)
  701.  
  702.        mov     bx,dx           (* BH := bit mask for first byte *)
  703.                                (* BL := bit mask for last byte *)
  704.        mov     dx,3CEh         (* DX := Graphics Controller port *)
  705.        mov     al,8            (* AL := Bit Mask Register number *)
  706.        mov     si,[CharMapPtr]
  707.  
  708. (* set pixels in leftmost byte of the line *)
  709.  
  710.        or      bh,bh
  711.        js      @L43             (* jump if byte-aligned (x1 is leftmost *)
  712.                                (*  pixel in byte) *)
  713.        or      cx,cx
  714.        jnz     @L42             (* jump if more than one byte in the line *)
  715.  
  716.        and     bl,bh           (* BL := bit mask for the line *)
  717.        jmp     @L44
  718.  
  719. @L42:  mov     ah,bh           (* AH := bit mask for 1st byte *)
  720.        mov     bh,[CurrentGraphWindow]
  721.        cmp     [si],bh
  722.        jnz     @L42a
  723.        out     dx,ax           (* update Graphics Controller *)
  724.        or      es:[di],al      (* update bit planes *)
  725. @L42a:
  726.        inc     di
  727.        inc     si
  728.        dec     cx
  729.  
  730. (* use a fast 8086 machine instruction to draw the remainder of the line *)
  731.  
  732. @L43:  jcxz    @L44
  733.        mov     ah,11111111b    (* AH := bit mask *)
  734.        out     dx,ax           (* update Bit Mask Register *)
  735.        mov     ah,[CurrentGraphWindow]
  736.  
  737. @L43a: cmp     [si],ah
  738.        jnz     @L43b
  739.        or      es:[di],al      (* update bit planes *)
  740. @L43b: inc     si
  741.        inc     di
  742.        loop    @L43a
  743.  
  744. (* set pixels in the rightmost byte of the line *)
  745.  
  746. @L44:  mov     ah,bl           (* AH := bit mask for last byte *)
  747.        mov     bl,[CurrentGraphWindow]
  748.        cmp     [si],bl
  749.        jnz     @L44a
  750.        out     dx,ax           (* update Graphics Controller *)
  751.        or      es:[di],al
  752. @L44a: sti
  753.  
  754. end;
  755.  
  756. (*Version 3 of this draw routine - includes partial overwrite protection *)
  757. procedure Draw_Any_Line_EGAVGA(X1,Y1,X2,Y2:word;Color:byte); assembler;
  758. asm
  759.        cli
  760.        push bp
  761.        mov     ax,[Y1]
  762.        mov     bx,[X1]
  763.        call    Do_TextAddr_EGAVGA
  764.        mov     [CharMapPtr],si
  765.        mov     [BitShift],dx
  766.        mov     [NegBitShift],bx
  767.        mov     [ReInitBit],ax
  768.  
  769.        mov     dx,EGAGraphController
  770.  
  771.        mov     ah,[Color]
  772.        xor     al,al
  773.        out     dx,ax
  774.  
  775.        mov     ax,Set_EnableSR+UseSR
  776.        out     dx,ax
  777.  
  778.        mov     ax,Default_RWFunction
  779.        mov     ah,[CurrentLineWriteMode]
  780.        shl     ah,1
  781.        shl     ah,1
  782.        shl     ah,1
  783.        out     dx,ax
  784.  
  785.        mov     ax,Default_WriteMode
  786.        out     dx,ax
  787.        mov     ax,Default_ColorPlane
  788.        out     dx,ax
  789.  
  790.        mov     si,[BytesPerLine]
  791.        mov     ax,EGAVideoMemory
  792.        mov     es,ax
  793.  
  794.        mov     cx,[x2]
  795.        sub     cx,[x1]
  796.  
  797.  
  798. @L01:  mov     bx,[y2]
  799.        sub     bx,[y1]         (* BX := y2 - y1 *)
  800.  
  801.        jns     @L03            (* jump if slope is positive *)
  802.        push    [NegBitShift]    (* Start with negative bit shift *)
  803.        pop     [BitShift]
  804.        neg     bx              (* BX := y1 - y2 *)
  805.        neg     si              (* negate increment for buffer interleave *)
  806.  
  807. (* select appropriate routine for slope of line *)
  808.  
  809. @L03:  mov     [VARvertincr],si  (* save vertical increment *)
  810.        mov     byte ptr [VARSlope],0
  811.        cmp     bx,cx
  812.        jle     @L04             (* jump if dy <= dx (slope <= 1) *)
  813.        mov     byte ptr [VARslope],1
  814.        xchg    bx,cx           (* exchange dy and dx *)
  815.  
  816. (* calculate initial decision variable and increments *)
  817.  
  818. @L04:  shl     bx,1            (* BX := 2 * dy *)
  819.        mov     [VARincr1],bx     (* incr1 := 2 * dy *)
  820.        sub     bx,cx
  821.        mov     si,bx           (* SI := d = 2 * dy - dx *)
  822.        sub     bx,cx
  823.        mov     [VARincr2],bx     (* incr2 := 2 * (dy - dx) *)
  824.  
  825. (* calculate first pixel address *)
  826.  
  827.        push    cx              (* preserve this register *)
  828.        mov     ax,[y1]         (* AX := y *)
  829.        mov     bx,[x1]         (* BX := x *)
  830.        call    Do_PixelAddr_EGAVGA
  831.                                (* ES:BX -> buffer *)
  832.                                (* CL := # bits to shift left *)
  833.  
  834.        mov     di,bx           (* ES:DI -> buffer *)
  835.        mov     ah,080h
  836.        shr     ah,cl           (* AH := bit mask in proper position *)
  837.        mov     bl,ah           (* AH,BL := bit mask *)
  838.        mov     al,8            (* AL := Bit Mask Register number *)
  839.        pop     cx              (* restore this register *)
  840.        inc     cx              (* CX := # of pixels to draw *)
  841.  
  842.        mov     bp,[CharMapPtr]
  843.        mov     bh,[CurrentGraphWindow]
  844.  
  845.        cmp     byte ptr [VARSlope],1
  846.        jz      @HiSlopeLine
  847.  
  848.        (* Use BP for CharMapPtr and BH for CurrentWindowId *)
  849.  
  850. @L10:  mov     ah,bl           (* AH := bit mask for next pixel *)
  851.  
  852. @L11:  or      ah,bl           (* mask current pixel position *)
  853.        ror     bl,1            (* rotate pixel value *)
  854.        jc      @L14            (* jump if bit mask rotated to *)
  855.                                (* leftmost pixel position *)
  856. (* bit mask not shifted out *)
  857.  
  858.        or      si,si            (* test sign of d *)
  859.        jns     @L12             (* jump if d >= 0 *)
  860.  
  861.        add     si,[VARincr1]    (* d := d + incr1 *)
  862.        loop    @L11
  863.  
  864.        cmp     ds:[bp],bh
  865.        jnz     @L11a
  866.  
  867.        out     dx,ax            (* update Bit Mask Register *)
  868.        or      es:[di],al       (* set remaining pixel(s) *)
  869. @L11a:
  870.        jmp     @LineDone
  871.  
  872. @L12:  add     si,[VARincr2]    (* d := d + incr2 *)
  873.        cmp     ds:[bp],bh
  874.        jnz     @L12a
  875.  
  876.        out     dx,ax            (* update Bit Mask Register *)
  877.        or      es:[di],al       (* update bit planes *)
  878.  
  879. @L12a: add     di,[VARvertincr] (* increment y *)
  880.        rol     word ptr [BitShift],1
  881.        jnc     @L12b
  882.  
  883.        add     bp,[VARVertincr]
  884.        push    [ReInitBit]
  885.        pop     [BitShift]
  886.  
  887. @L12b: loop    @L10
  888.        jmp     @LineDone
  889.  
  890. (* bit mask shifted out *)
  891.  
  892. @L14:  cmp     ds:[bp],bh
  893.        jnz     @L14a
  894.  
  895.        out     dx,ax           (* update Bit Mask Register ... *)
  896.        or      es:[di],al      (* update bit planes *)
  897.  
  898. @L14a: inc     di              (* increment x *)
  899.        inc     bp
  900.  
  901.        or      si,si           (* test sign of d *)
  902.        jns     @L15             (* jump if non-negative *)
  903.  
  904.        add     si,[VARincr1]     (* d := d + incr1 *)
  905.        loop    @L10
  906.        jmp     @LineDone
  907.  
  908. @L15:  add     si,[VARincr2]     (* d := d + incr2 *)
  909.        add     di,[VARvertincr]  (* vertical increment *)
  910.  
  911.        rol     word ptr [BitShift],1
  912.        jnc     @L15a
  913.  
  914.        add     bp,[VARVertincr]
  915.        push    [ReInitBit]
  916.        pop     [BitShift]
  917.  
  918. @L15a: loop    @L10
  919.        jmp     @LineDone
  920.  
  921.  
  922. (* routine for dy > dx (slope > 1)  *)
  923.        (* ES:DI -> video buffer *)
  924.        (* AH = bit mask for 1st pixel *)
  925.        (* AL = Bit Mask Register number *)
  926.        (* CX = #pixels to draw *)
  927.        (* DX = Graphics Controller port addr *)
  928.        (* SI = decision variable *)
  929.  
  930. (* Use BP for CharMapPtr and BH for CurrentWindowId *)
  931. @HiSlopeLine:
  932.  
  933. @L21:  cmp     ds:[bp],bh
  934.        jnz     @L21a
  935.        out     dx,ax           (* update Bit Mask Register *)
  936.        or      es:[di],al      (* update bit planes *)
  937. @L21a:
  938.        add     di,[VARvertincr] (* increment y *)
  939.        rol     word ptr [BitShift],1
  940.        jnc     @L22
  941.  
  942.        add     bp,[VARVertincr]    (* Update char position vertically *)
  943.        push    [ReInitBit]
  944.        pop     [BitShift]
  945.  
  946. @L22:  or      si,si           (* test sign of d *)
  947.        jns     @L23             (* jump if d >= 0 *)
  948.  
  949.        add     si,[VARincr1]     (* d := d + incr1 *)
  950.        loop    @L21
  951.        jmp     @LineDone
  952.  
  953.  
  954. @L23:  add     si,[VARincr2]   (* d := d + incr2 *)
  955.  
  956.        ror     ah,1            (* rotate bit mask *)
  957.        adc     di,0            (* increment DI if when mask rotated to *)
  958.                                (*  leftmost pixel position *)
  959.        rol     ah,1
  960.        ror     ah,1
  961.        adc     bp,0            (* Update char position horizontally *)
  962.  
  963.        loop    @L21
  964.  
  965. @LineDone:
  966.        pop     bp
  967.        sti
  968. end;
  969.  
  970.  
  971.  
  972. procedure Do_Set_EGAVGA;
  973. begin
  974.   Do_INIT_X:=Do_INIT_EGAVGA;
  975.   Do_DONE_X:=Do_DONE_EGAVGA;
  976.   TVGraphCursorOn_X:=@TVGraphCursorOn_EGAVGA;
  977.   TVGraphCursorOff_X:=@TVGraphCursorOff_EGAVGA;
  978.   TVUpdateCursor_X:=@TVUpdateCursor_EGAVGA;
  979.   Do_GraphMOV_X:=@Do_GraphMOV_EGAVGA;
  980.   NewJmp_GraphMOV_X:=@NewJmp_GraphMOV_EGAVGA;
  981.   Draw_Any_Line_X:=Draw_Any_Line_EGAVGA;
  982.   Draw_Horiz_Line_X:=Draw_Horiz_Line_EGAVGA;
  983.   Draw_Vert_Line_X:=Draw_Vert_Line_EGAVGA;
  984. end;
  985.  
  986.